<?php
/**
 *  缓存处理类
 *  处理缓存的操作类
 *
 *  @author jerry <jerryjiang15@gmail.com>
 *  @version 1.0
 */

class Cache
{
    var $cache_root;         //缓存存放目录
    var $cache_vaild_time;   //缓存过期时间
    var $use_hash_dir;       //是否使用多层哈希目录,产生海量缓存时使用

    /**
     * 析构函数
     * @return void
     */
    function __construct($cache_root = '.',$cache_vaild_time = 3600, $use_hash_dir = false)
    {
        $this->cache_root       = $cache_root;
        $this->cache_vaild_time = $cache_vaild_time > 0 ? $cache_vaild_time : 3600;
        $this->use_hash_dir    = $use_hash_dir;
    }

    /**
     * 设置缓存数据
     * @param $app_name    //应用名称
     * @param $var_name    //保存缓存的变量名
     * @param $data        //需要缓存的数组或字符串
     * @return boolean
     */
    function setCache($app_name,$var_name,$data)
    {
        $return = false;

        if(empty($app_name) || empty($var_name) || empty($data))
        {
            return $return;
        }

        $cache_path = $this->getCacheDir($app_name,$var_name);
echo $cache_path;
        if(empty($cache_path))
        {
            return $return;
        }

        $return = $this->wirteFile($cache_path,$data);

        return $return;
    }

    /**
     * 得到缓存数据
     * @param $app_name   	 //应用名称
     * @param $var_name      //保存缓存的变量名
     * @return $data         //缓存的数组或字符串
     */
    function getCache($app_name,$var_name)
    {
        $data = array();

        if(empty($app_name) || empty($var_name))
        {
            return $data;
        }

        $cache_path = $this->getCacheDir($app_name,$var_name);

        $data = $this->readFile($cache_path);

        return $data;
    }

    /**
     * 判断缓存是否有效
     * @param $app_name    //应用名称
     * @param $var_name    //保存缓存的变量名
     * @return boolean
     */
    function isValid($app_name,$var_name)
    {
        if(empty($app_name) || empty($var_name))
        {
            return false;
        }

        $cache_path = $this->getCacheDir($app_name,$var_name);

        if(!is_file($cache_path))
        {
            return false;
        }

        if(filemtime($cache_path) + $this->cache_vaild_time >= time())
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    /**
     * 清除指定缓存
     * @param $app_name    // 应用名称
     * @param $var_name    // 保存缓存的变量名
     * @return boolean
     */
    function clearCache($app_name, $var_name)
    {
        if ( empty($app_name) || empty($var_name) )
        {
            return true;
        }

        $cache_path = $this->getCacheDir($app_name, $var_name);

        if ( !is_file($cache_path) )
        {
            return true;
        }

        return @unlink($cache_path);
    }

    /**
     * 得到缓存目录
     * @param $app_name    //应用名称
     * @param $var_name    //保存缓存的变量名
     * @return $rec_data
     */
    function getCacheDir($app_name,$var_name)
    {
        $rec_data = array();

        if(empty($app_name) || empty($var_name))
        {
            return false;
        }

        $app_dir = $this->cache_root . $app_name;

        if(!is_dir($app_dir))
        {
            $ret = mkdir($app_dir, 0775, true);

            if(!$ret)
            {
                return $rec_data;
            }
        }

        if($this->use_hash_dir)
        {
            $hash = $this->hash($var_name);
            $hash = sprintf('%06u',$hash);

            $dir_1 = substr($hash, -4, 2);
            $dir_2 = substr($hash, -2);

            $app_dir = $app_dir . '/' . $dir_1 . '/' . $dir_2;

            if(!is_dir($app_dir))
            {
                mkdir($app_dir , 0755 , 1);
            }
        }

        return $app_dir . '/' . md5($var_name) . '.php';
    }

    /**
     * 读取缓存文件
     * @param $file_name    //文件名
     * @return $data        //缓存文件
     */
    function readFile($file_name)
    {
        $data = array();

        if(!file_exists($file_name))
        {
            return $data;
        }

        //动态载入cache数据
        require($file_name);

        $data = isset($data_arr) ? $data_arr : NULL;

        return $data;
    }

    /**
     * 写缓存文件
     *
     * @param $file_name       //文件名
     * @param $data            //文件数据
     * @return unknown_type
     */
    function wirteFile($file_name,$data)
    {
        if(empty($file_name) || empty($data))
        {
            return false;
        }

        $fp = fopen($file_name, "w");

        if(!$fp)
        {
            return false;
        }

        flock($fp, LOCK_EX);

        //数据格式化, 转换为php类型数据
        $php_data = "<?php\n";
         $php_data .= "\$data_arr = ".var_export($data, true).";\n";
         $php_data .= "?>";

        fwrite($fp, $php_data);
        flock($fp, LOCK_UN);
        fclose($fp);

        return true;
    }

    /**
     * 生成哈希数
     *
     * @param string $str
     * @return int
     */
    function hash($str)
    {
        $str = strval($str);    // convert numerical key to string
        $hash = 0;
        $n = strlen($str);

        for ($i = 0; $i <$n; $i++)
        {
            $hash ^= (ord($str[$i]) <<($i & 0x0f));
        }

        return $hash % 701819;
    }
}

/*
$root_dir = "./";

$app_name  = "sys";    //缓存类型

$var = "base_info";    //缓存名称

$cache = new Cache($root_dir,3600,true);

if($cache->isValid($app_name, $var))    //如果缓存失效或者不存在
{
    echo 'set cache';   //重新生成缓存内容

    $data = array( array('UserID'=>'123123','name' => 'jerry','age'=> 18) , array('UserID'=>'321321','name' => 'tango','age'=> 53));

    $cache->setCache($app_name, $var, $data);
}

$ret = $cache->getCache($app_name, $var);   //得到缓存数据

print_r($ret);
 */
?>
